package com.kds.smarthome.service;

import com.kds.smarthome.common.EnergyType;
import com.kds.smarthome.common.StatisticsType;
import com.kds.smarthome.entity.Function;
import com.kds.smarthome.mapper.FunctionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class FunctionService {

    @Autowired
    private FunctionMapper functionMapper;

    /**
     * 根据建筑编码查询累计值类型的功能点列表
     * @param buildingCode 建筑编码
     * @return 名称和FID列表
     */
    public List<Map<String, String>> findAccumulateFunctions(String buildingCode) {
        log.debug("Query accumulate functions for building: {}", buildingCode);

        return functionMapper.findNameAndFidsByBuildingCodeAndTypes(
            buildingCode,
            null,   // name为空
            null,   // energyType为空
            StatisticsType.ACCUMULATE.getCode()  // 固定为accumulate
        );
    }

    /**
     * 根据建筑编码和类型查询功能点ID列表
     * @param buildingCode 建筑编码
     * @param name 功能点名称
     * @param energyType 能源类型
     * @param statisticsType 统计类型
     * @return FID列表
     */
    public List<String> findFidsByBuildingCodeAndTypes(
            String buildingCode,
            String name,
            EnergyType energyType,
            StatisticsType statisticsType) {

        log.debug("Query fids by buildingCode: {}, name: {}, energyType: {}, statisticsType: {}",
            buildingCode, name, energyType, statisticsType);

        return functionMapper.findFidsByBuildingCodeAndTypes(
            buildingCode,
            name,
            energyType != null ? energyType.getCode() : null,
            statisticsType != null ? statisticsType.getCode() : null
        );
    }

    /**
     * 根据建筑编码和类型查询功能点名称和ID列表
     * @param buildingCode 建筑编码
     * @param name 功能点名称
     * @param energyType 能源类型
     * @param statisticsType 统计类型
     * @return 名称和FID列表
     */
    public List<Map<String, String>> findNameAndFidsByBuildingCodeAndTypes(
            String buildingCode,
            String name,
            EnergyType energyType,
            StatisticsType statisticsType) {

        log.debug("Query name and fids by buildingCode: {}, name: {}, energyType: {}, statisticsType: {}",
            buildingCode, name, energyType, statisticsType);

        return functionMapper.findNameAndFidsByBuildingCodeAndTypes(
            buildingCode,
            name,
            energyType != null ? energyType.getCode() : null,
            statisticsType != null ? statisticsType.getCode() : null
        );
    }

    public List<Function> selectEnergyFunctions(String buildingCode){
        return  functionMapper.selectEnergyFunctions(buildingCode);
    }

    /**
     * 根据ID查询功能点
     */
    public Function findById(Integer tid) {
        return functionMapper.findById(tid);
    }

    /**
     * 根据FID查询功能点
     */
    public Function findByFid(String fid) {
        return functionMapper.findByFid(fid);
    }

    /**
     * 查询所有功能点
     */
    public List<Function> findAll() {
        return functionMapper.findAll();
    }

    /**
     * 根据建筑编码查询功能点列表
     */
    public List<Function> findByBuildingCode(String buildingCode) {
        return functionMapper.findByBuildingCode(buildingCode);
    }

    /**
     * 新增功能点
     */
    public void create(Function function) {
        functionMapper.insert(function);
    }

    /**
     * 更新功能点
     */
    public void update(Function function) {
        functionMapper.update(function);
    }

    /**
     * 删除功能点
     */
    public void delete(Integer tid) {
        functionMapper.delete(tid);
    }

    /**
     * 批量删除功能点
     */
    public void batchDelete(List<Integer> tids) {
        functionMapper.batchDelete(tids);
    }

    /**
     * 根据条件查询功能点列表
     */
    public List<Function> findByCondition(Function function) {
        return functionMapper.findByCondition(function);
    }

    /**
     * 统计功能点数量
     */
    public long count(Function function) {
        return functionMapper.count(function);
    }

    /**
     * 分页查询功能点列表
     * @param function 查询条件
     * @param pageNum 页码（从1开始）
     * @param pageSize 每页记录数
     * @return 功能点列表
     */
    public List<Function> findByPage(Function function, Integer pageNum, Integer pageSize) {
        // 计算偏移量：(页码-1) * 每页记录数
        int offset = (pageNum - 1) * pageSize;
        log.debug("分页查询参数：pageNum={}, pageSize={}, offset={}", pageNum, pageSize, offset);
        return functionMapper.findByPage(function, offset, pageSize);
    }

    /**
     * 分页查询功能点列表（带排序）
     * @param function 查询条件
     * @param pageNum 页码（从1开始）
     * @param pageSize 每页记录数
     * @param sortField 排序字段
     * @param sortOrder 排序方式（asc/desc）
     * @return 功能点列表
     */
    public List<Function> findByPageWithSort(
            Function function,
            Integer pageNum,
            Integer pageSize,
            String sortField,
            String sortOrder) {
        // 计算偏移量：(页码-1) * 每页记录数
        int offset = (pageNum - 1) * pageSize;
        log.debug("分页查询参数：pageNum={}, pageSize={}, offset={}, sortField={}, sortOrder={}", 
            pageNum, pageSize, offset, sortField, sortOrder);
        return functionMapper.findByPageWithSort(function, offset, pageSize, sortField, sortOrder);
    }

    /**
     * 批量创建功能点
     * @param functions 功能点列表
     */
    @Transactional
    public void batchCreate(List<Function> functions) {
        if (functions == null || functions.isEmpty()) {
            return;
        }
        
        // 检查fid是否重复
        List<String> fids = functions.stream()
            .map(Function::getFid)
            .collect(Collectors.toList());
            
        List<Function> existingFunctions = functionMapper.findByFids(fids);
        if (!existingFunctions.isEmpty()) {
            throw new RuntimeException("存在重复的功能点FID：" + 
                existingFunctions.stream()
                    .map(Function::getFid)
                    .collect(Collectors.joining(", ")));
        }
        
        // 批量插入
        for (Function function : functions) {
            functionMapper.insert(function);
        }
    }
}
